package cn.jdemo.type;


import java.lang.reflect.*;
import java.util.List;

/**
 * @see java.lang.reflect.GenericDeclaration
 * @see GenericDeclaration#getTypeParameters() {@code TypeVariable}对象的数组，这些对象表示此泛型声明所声明的类型变量
 *
 * 其子类
 * @see java.lang.Class
 * @see Class#getTypeParameters()
 *
 * @see java.lang.reflect.Method
 * @see Method#getTypeParameters()
 *
 * @see java.lang.reflect.Constructor
 * @see Constructor#getTypeParameters()
 *
 *
 * @date 2020/12/29
 */
public class Demo05_GenericDeclaration<Z extends Object> {
    public static void main(String[] args) {
        // test01();
        // test02();
        test03();
    }

    public <T> Demo05_GenericDeclaration(List<? extends T> list01){
    }
    /*<V> Demo05_GenericDeclaration(ArrayList<V super Number> list02){
    }*/
    public static <K> void temp01(List<? extends K> list01) {
    }
    /*public static <Z> void temp02(List<Z super Number> list01) {
    }*/

    /**
     * 输出内容
     * *********Class#getTypeParameters()************
     * Name():Z
     * TypeName():Z
     * Bounds()java.lang.Object
     *
     * @see java.lang.Class
     * @see Class#getTypeParameters()
     *
     */
    public static void test01() {
        Class<Demo05_GenericDeclaration> cls = Demo05_GenericDeclaration.class;
        TypeVariable<Class<Demo05_GenericDeclaration>>[] typeParameters = cls.getTypeParameters();
        for (TypeVariable typeVariable:typeParameters){
            System.out.println("*********Class#getTypeParameters()************");
            System.out.println("Name():"+typeVariable.getName());
            System.out.println("TypeName():"+typeVariable.getTypeName());
            Type[] bounds = typeVariable.getBounds();
            for (Type type:bounds){
                System.out.println("Bounds()"+type.getTypeName());
            }
        }
    }

    /**
     * 输出内容：
     * *********Constructor#getTypeParameters()************
     * Name():T
     * TypeName():T
     * Bounds()java.lang.Object
     *
     * @see java.lang.reflect.Constructor
     * @see Constructor#getTypeParameters()
     */
    public static void test02() {
        Constructor<Demo05_GenericDeclaration> constructor = null;
        try {
            constructor = Demo05_GenericDeclaration.class.getConstructor(List.class);
            TypeVariable<Constructor<Demo05_GenericDeclaration>>[] typeParameters = constructor.getTypeParameters();
            for (TypeVariable typeVariable:typeParameters){
                System.out.println("*********Constructor#getTypeParameters()************");
                System.out.println("Name():"+typeVariable.getName());
                System.out.println("TypeName():"+typeVariable.getTypeName());
                Type[] bounds = typeVariable.getBounds();
                for (Type type:bounds){
                    System.out.println("Bounds()"+type.getTypeName());
                }
            }

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    /**
     * 输出内容:
     * *********Method#getTypeParameters()************
     * Name():K
     * TypeName():K
     * Bounds()java.lang.Object
     *
     * @see java.lang.reflect.Method
     * @see Method#getTypeParameters()
     */
    public static void test03() {
        Method method = null;
        try {
            method = Demo05_GenericDeclaration.class.getMethod("temp01", List.class);
            TypeVariable<Method>[] typeParameters = method.getTypeParameters();
            for (TypeVariable typeVariable:typeParameters){
                System.out.println("*********Method#getTypeParameters()************");
                System.out.println("Name():"+typeVariable.getName());
                System.out.println("TypeName():"+typeVariable.getTypeName());
                Type[] bounds = typeVariable.getBounds();
                for (Type type:bounds){
                    System.out.println("Bounds()"+type.getTypeName());
                }
            }

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}